/////////////////////////////////////////////////////////////////////////////
// Name:        varianthandlers.h
// Purpose:     Handlers to create, read and write variants
// Author:      Julian Smart
// Modified by:
// Created:     2006-05-11
// RCS-ID:      $$
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _WX_VARIANTHANDLERS_H_
#define _WX_VARIANTHANDLERS_H_

#include "wx/defs.h"
#include "wx/variant.h"

class WXDLLEXPORT wxOutputStream;
class WXDLLEXPORT wxInputStream;
class WXDLLEXPORT wxDataOutputStream;
class WXDLLEXPORT wxDataInputStream;

/*!
 * A wxVariantHandler knows how to create, load and save a variant of a particular
 * type.
 */

class wxVariantHandler: public wxObject
{
    DECLARE_CLASS(wxVariantHandler)
public:
    wxVariantHandler(const wxString& name = wxEmptyString)
        : m_name(name)
        { }

    virtual bool ReadValue(const wxString& type, wxVariant& variant, wxInputStream& stream, wxDataInputStream& dataStream) = 0;
    virtual bool WriteValue(const wxVariant& variant, wxOutputStream& stream, wxDataOutputStream& dataStream) = 0;

    virtual bool CanRead(wxInputStream& WXUNUSED(stream)) { return true; }
    virtual bool CanHandle(const wxString& type) = 0;

    /// Supply a default value for this type
    virtual wxVariant GetDefaultValue(const wxString& type) = 0;

    void SetName(const wxString& name) { m_name = name; }
    const wxString& GetName() const { return m_name; }

protected:

    wxString  m_name;
};

/*!
 * wxVariantHandlers stores objects that know about particular variant types
 */

class wxVariantHandlers: public wxObject
{
DECLARE_CLASS(wxVariantHandlers)
public:

// Construction & destruction

    wxVariantHandlers() {}
    ~wxVariantHandlers() {}

    static bool CanHandle(const wxString& type);
    static bool Read(wxVariant& variant, wxInputStream& stream, wxDataInputStream& dataStream);
    static bool Write(const wxVariant& variant, wxOutputStream& stream, wxDataOutputStream& dataStream);

    /// Gets a default value for this type
    static wxVariant GetDefaultValue(const wxString& type);

    static wxList& GetHandlers() { return sm_handlers; }
    static void AddHandler(wxVariantHandler *handler);
    static void InsertHandler(wxVariantHandler *handler);
    static bool RemoveHandler(const wxString& name);
    static wxVariantHandler *FindHandlerByName(const wxString& name);
    static wxVariantHandler *FindHandlerByType(const wxString& type);

    static void CleanUpHandlers();
    static void InitStandardHandlers();

private:

    static wxList   sm_handlers;
};

/// Read a variant
bool wxReadVariant(wxVariant& variant, wxInputStream& stream, wxDataInputStream& dataStream);

/// Write a variant
bool wxWriteVariant(const wxVariant& variant, wxOutputStream& stream, wxDataOutputStream& dataStream);

/// Insertion and extraction operators
wxOutputStream& operator<<(wxOutputStream& stream, const wxVariant& variant);
wxInputStream& operator>>(wxInputStream& stream, wxVariant& variant);

#endif
    // _WX_VARIANTHANDLERS_H_
